한국어로 먼저 쓰고 영어로 옮기는 워크플로를 전제로 정리한 문서. 한국어 초안 템플릿 → 영어 대응 표현 → 실제 제출 사례 순서.
근거는 두 가지: ① GlueSQL 저장소에 머지된 타인의 PR(#2001, #2012, #2013), ② 내가 직접 작성한 PR(#1972, #1980 머지 / #2016 클로즈).
📌 개념
대전제 — 템플릿 파일이 없는 저장소가 많다
GlueSQL에는 .github/PULL_REQUEST_TEMPLATE.md가 없음. CONTRIBUTING.md도 없음. 이런 저장소에서는 최근 머지된 PR 본문을 읽고 관행을 역추적하는 게 유일한 방법.
# 저장소 관행 파악용 명령gh pr list --repo <owner>/<repo> --state merged --limit 5 --json number,title,body# 내가 과거에 쓴 PR 다시 보기gh pr list --repo <owner>/<repo> --author <myname> --state all --limit 20 --json number,title,state,body# 템플릿 파일 존재 여부find .github -iname "*pull_request*"
TIP
템플릿이 없다고 아무렇게나 쓰면 리뷰어가 맥락을 재구성하느라 리뷰가 느려짐. 관행을 따르는 것 자체가 리뷰 비용을 낮추는 기여.
PR 본문이 답해야 하는 4가지 질문
형식이 무엇이든 리뷰어의 머릿속 질문은 동일함.
질문
대응 섹션
뭐가 문제였나?
Summary 앞부분 (증상 + 원인)
뭘 바꿨나?
Summary 불릿 / Changes
왜 이 범위인가? (왜 더/덜 안 했나)
Scope note / Known limitations
정말 동작하나?
Test plan / Testing
3번을 빼먹는 경우가 많은데, 리뷰어가 가장 궁금해하는 지점이라 명시하면 왕복이 크게 줄어듦.
🧩 한국어 초안 템플릿
기본형 (버그 수정 / 소규모 기능)
**Summary**<한 문단: 현재 코드가 무엇을 잘못하고 있는지 + 왜 문제인지><한 문단: 이 PR이 무엇을 바꾸는지>**Changes**- `경로/파일.rs`: <무엇을 어떻게>- `경로/테스트.rs`: <어떤 케이스를 추가/수정>**Test plan**- [x] `cargo test -p ...` — N개 통과- [x] `cargo clippy --all-targets -- -D warnings` — 클린- [x] `cargo fmt --all -- --check`Closes #<이슈번호>
확장형 (범위 판단이 필요한 경우)
**Summary**<문제 설명>**Scope note:** <왜 A는 건드리지 않았는지. 별건으로 분리한 이유>**Changes**- ...**Known limitations**- <이 PR로도 남는 구멍 + 후속 계획>**Test plan**- [x] ...Closes #<이슈번호>
IMPORTANT
Closes #N / Fixes #N을 본문에 쓰면 머지 시 이슈가 자동으로 닫힘. 이슈를 닫으면 안 되는 경우(부분 해결)는 Related to #N을 씀 — GlueSQL 2028이 이 형태.
잘한 점: “기존 UnsupportedInsertOption/UnsupportedUpdateOption과 같은 패턴을 따름” — 새 컨벤션을 만든 게 아니라는 신호
#1980 — Use typed enums for unsupported SQL options in translate errors (MERGED)
구조: **Summary**(산문 + 변환 목록 7개) / **Test plan**(체크박스 5개) / Closes #1975
핵심 포인트 — 범위 확장의 정당화:
“The issue only listed the first 5 as examples. UnsupportedCreateTableOption and UnsupportedJoinConstraint have the exact same closed-set-of-strings pattern, so I included them too rather than leaving inconsistent holdouts.”
이슈가 시킨 것보다 더 했을 때 왜 그게 맞는지 먼저 설명. 이게 없으면 리뷰어가 “왜 범위를 넘었냐”고 물음.
핵심 포인트 — 설계 선택의 근거: Serialize를 derive 대신 collect_str 위임으로 구현한 이유를 “문자열이 두 군데로 갈라져 실제로 회귀가 났었다”는 개발 중 겪은 사실로 뒷받침
핵심 포인트 — 전체를 못 돌렸을 때: 13개 스토리지 중 1개만 돌리고 “translate()가 스토리지를 건드리기 전에 실행되므로 이 하나가 전체를 대표한다”고 논리로 커버
#2016 — Write file-storage row data atomically... (CLOSED, 미머지)
구조: ## Summary / ## Changes / ## Known limitations / ## Test plan
잘한 점: Scope note로 delete_data를 왜 안 건드렸는지 명시 (단일 unlink는 이미 원자적)
잘한 점: Known limitations에 남은 크래시 윈도우를 스스로 먼저 공개
교훈: 본문 품질과 머지 여부는 별개. 클로즈 사유는 본문이 아니라 범위·설계 합의 문제였음 → 큰 변경은 PR 전에 이슈에서 방향 합의를 먼저 받는 게 나음
WARNING
Known limitations를 쓸 때는 반드시 후속 계획과 함께 적을 것. 한계만 나열하면 “미완성 PR”로 읽히고, 후속이 붙으면 “범위를 통제한 PR”로 읽힘.